package req

import (
	"project-info/src/lib"

	"github.com/gin-gonic/gin"
)

// LogInfo 日志信息
type LogInfo struct {
	Description string // 请求描述

	LogResp bool // 是否记录返回结果
	save    bool // 是否保存日志
}

// 请求配置，如是否需要权限，日志信息等配置
type Conf struct {
	method  string
	path    string
	handler lib.HandlerFunc // 请求处理函数

	beforeAuthMiddleware []lib.MiddlewareFunc // 鉴权前中间件
	middleware           []lib.MiddlewareFunc // 中间件
	requiredPermission   *Permission          // 需要的权限信息，默认为nil，需要校验token
	logInfo              *LogInfo             // 日志相关信息
	noRes                bool                 // 无需返回结果，即文件下载等
}

func New(method, path string, handler lib.HandlerFunc) *Conf {
	return &Conf{method: method, path: path, handler: handler, noRes: false}
}

func NewPost(path string, handler lib.HandlerFunc) *Conf {
	return New("POST", path, handler)
}

func NewGet(path string, handler lib.HandlerFunc) *Conf {
	return New("GET", path, handler)
}

func NewPut(path string, handler lib.HandlerFunc) *Conf {
	return New("PUT", path, handler)
}

func NewDelete(path string, handler lib.HandlerFunc) *Conf {
	return New("DELETE", path, handler)
}

func NewGroup(path string) *Conf {
	return &Conf{path: path, noRes: false}
}

func (r *Conf) ToGinHandler() []gin.HandlerFunc {
	var handlers []gin.HandlerFunc

	// 添加鉴权前中间件
	for _, middleware := range r.beforeAuthMiddleware {
		handlers = append(handlers, lib.WrapMiddleware(middleware))
	}

	// 添加权限相关中间件
	if r.requiredPermission != nil {
		if r.requiredPermission.NeedToken {
			// 新增token校验中间件
			handlers = append(handlers, lib.WrapMiddleware(JwtHandlerConfig()))
		}
		if r.requiredPermission.Code != "" {
			// 新增权限校验中间件
			handlers = append(handlers, lib.WrapMiddleware(PermissionHandlerConfig(r.requiredPermission)))
		}
	}

	// 添加普通中间件
	for _, middleware := range r.middleware {
		handlers = append(handlers, lib.WrapMiddleware(middleware))
	}

	// 添加处理函数
	if r.handler != nil {
		handlers = append(handlers, lib.WrapHandler(r.handler))
	}

	return handlers
}

// 调用该方法设置请求描述，则默认记录日志，并不记录响应结果
func (r *Conf) Log(li *LogInfo) *Conf {
	r.logInfo = li
	return r
}

// 设置请求上下文需要的权限信息
func (r *Conf) RequiredPermission(permission *Permission) *Conf {
	r.requiredPermission = permission
	return r
}

// 设置请求上下文需要的权限信息
func (r *Conf) RequiredPermissionCode(code string) *Conf {
	r.RequiredPermission(NewPermission(code))
	return r
}

// 不需要token校验
func (r *Conf) DontNeedToken() *Conf {
	r.requiredPermission = &Permission{NeedToken: false}
	return r
}

// 需要token校验
func (r *Conf) NeedToken() *Conf {
	r.requiredPermission = &Permission{NeedToken: true}
	return r
}

// 没有响应结果，即文件下载等
func (r *Conf) NoRes() *Conf {
	r.noRes = true
	return r
}

// 添加中间件
func (r *Conf) WithMiddleware(middleware ...lib.MiddlewareFunc) *Conf {
	r.middleware = append(r.middleware, middleware...)
	return r
}

// 添加鉴权前中间件
func (r *Conf) WithBeforeAuthMiddleware(middleware ...lib.MiddlewareFunc) *Conf {
	r.beforeAuthMiddleware = append(r.beforeAuthMiddleware, middleware...)
	return r
}

// 初始化group
func (r *Conf) SetUpGroup(e *gin.Engine) *gin.RouterGroup {
	return e.Group(r.path, r.ToGinHandler()...)
}

// 注册
func (r *Conf) SetUpRouterWithEngine(e *gin.Engine) *Conf {
	handlers := r.ToGinHandler()
	switch r.method {
	case "GET":
		e.GET(r.path, handlers...)
	case "POST":
		e.POST(r.path, handlers...)
	case "PUT":
		e.PUT(r.path, handlers...)
	case "DELETE":
		e.DELETE(r.path, handlers...)
	case "PATCH":
		e.PATCH(r.path, handlers...)
	case "OPTIONS":
		e.OPTIONS(r.path, handlers...)
	case "ANY":
		e.Any(r.path, handlers...)
	default:
		panic("method not support")
	}
	return r
}

// 注册至RouterGroup
func (r *Conf) SetUpRouter(group *gin.RouterGroup) *Conf {
	handlers := r.ToGinHandler()
	switch r.method {
	case "GET":
		group.GET(r.path, handlers...)
	case "POST":
		group.POST(r.path, handlers...)
	case "PUT":
		group.PUT(r.path, handlers...)
	case "DELETE":
		group.DELETE(r.path, handlers...)
	case "PATCH":
		group.PATCH(r.path, handlers...)
	case "OPTIONS":
		group.OPTIONS(r.path, handlers...)
	case "ANY":
		group.Any(r.path, handlers...)
	default:
		panic("method not support")
	}
	return r
}

// 批量注册至RouterGroup
func BatchSetUpRouter(group *gin.RouterGroup, reqs []*Conf) {
	for _, req := range reqs {
		req.SetUpRouter(group)
	}
}
